// 给你一个嵌套的整型列表。请你设计一个迭代器，使其能够遍历这个整型列表中的所有整数。
// 列表中的每一项或者为一个整数，或者是另一个列表。其中列表的元素也可能是整数或是其他列表。


// 示例 1:
// 输入: [[1,1],2,[1,1]]
// 输出: [1,1,2,1,1]
// 解释: 通过重复调用 next 直到 hasNext 返回 false，next 返回的元素的顺序应该是: [1,1,2,1,1]。

// 示例 2:
// 输入: [1,[4,[6]]]
// 输出: [1,4,6]
// 解释: 通过重复调用 next 直到 hasNext 返回 false，next 返回的元素的顺序应该是: [1,4,6]。


/**
 * this is the dataStructure definition
 * 
 * 
 * function NestedInteger() {
 *
 *     isInteger is executed to judge whether it is a singleInter
 *     @return {boolean}
 *     this.isInteger = function() {
 *         ...
 *     };
 *
 *     if it is a single interger, execute getInterger to get its value
 *     @return {integer}
 *     this.getInteger = function() {
 *         ...
 *     };
 *
 *     if it is an array, execute getList to get its array return
 *     @return {NestedInteger[]}
 *     this.getList = function() {
 *         ...
 *     };
 * };
 * 
 * 
 * 
 * Your NestedIterator will be called like this:
 * 
 * var i = new NestedIterator(nestedList), a = [];
 * 
 * while (i.hasNext()) a.push(i.next());
 *
 */



// ==================================暴力扁平化================================
/**
 * @constructor
 * @param {NestedInteger[]} nestedList
 */
var NestedIterator = function (nestedList) {
  // 初始化数组指针
  this.index = 0;
  // 扁平化函数
  let flatten = function flatten(list, arr = []) {
    // 遍历NestedInteger数据结构（list一定是一个数组）
    list.forEach(item => {
      // 项是单个值
      if (item.isInteger()) {
        arr.push(item.getInteger());
      }
      // 项任然是一个数组
      else {
        flatten(item.getList(), arr);
      }
    });
    return arr;
  }
  // 初始化扁平化数组
  this.array = flatten(nestedList);
  // 初始化迭代标识符
  if (this.array.length === 0) {
    this.canDoing = false;
  } else {
    this.canDoing = true;
  }
};


/**
* @this NestedIterator
* @returns {boolean}
*/
NestedIterator.prototype.hasNext = function () {
  return this.canDoing;
};

/**
* @this NestedIterator
* @returns {integer}
*/
NestedIterator.prototype.next = function () {
  let res = this.array[this.index];
  this.index++;
  // 遍历到最后需要翻转迭代标识符
  if (this.index === this.array.length) {
    this.canDoing = false;
  }
  return res;
};



// ============================Generator步进函数惰性迭代=============================
// 利用*函数使得不在构造时直接将数组所有项扁平化并存储，而是每调用一次next时才输出一个
var NestedIterator = function (nestedList) {
  let gen = function* gen(list) {
    for (let i = 0; i <= list.length - 1; i++) {
      if (list[i].isInteger()) {
        yield list[i].getInteger();
      } else {
        yield* gen(list[i].getList());
      }
    }
  }
  // 初始化迭代器
  this.iterator = gen(nestedList);
  // 初始化值
  this.val = undefined;
};


NestedIterator.prototype.hasNext = function () {
  let { done, value } = this.iterator.next();
  this.val = value;
  return !done;
};

NestedIterator.prototype.next = function () {
  return this.val;
};